package com.zed.api.domain.currentuser;


import com.zed.api.common.adpt.Adaptable;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collection;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;


/**
 * 当前用户，代表当前正在操作系统功能的访问者。它可能是自然人，也可能是程序进程或者某个终端设备。
 *
 * @author Zed
 */
public interface CurrentUser extends Adaptable {

    /**
     * 当前用户持有的账号
     *
     * @return {@link Account},可能返回匿名账号
     */
    Account getAccount();


    /**
     * 获取当前用户的会话
     *
     * @return {@link Session},可能返回null.
     */
    default Session getSession() {
        return this.getSession(false);
    }

    /**
     * 获取当前用户的会话
     *
     * @param create {@link boolean},如果会话不存在，则创建
     * @return {@link Session},可能返回null.
     */
    Session getSession(boolean create);

    /**
     * 判断是否持有{@code permission}授权
     *
     * @param permission {@link String},权限
     * @return {@link boolean},返回{@code true}表示持有
     */
    boolean isPermitted(String permission);

    /**
     * 判断是否持有{@code permissions}权限
     *
     * @param permissions
     * @return {@link boolean[]},每一个权限返回一个对应的boolean
     */
    boolean[] isPermitted(String... permissions);

    /**
     * 判断是否持有所有{@code  permissions}授权
     *
     * @param permissions {@link String...},权限集
     * @return {@link boolean},全部持有返回{@code true},否则返回{@code false}
     */
    boolean isPermittedAll(String... permissions);

    /**
     * 检查持有{@code permission}授权
     *
     * @param permission 权限
     * @throws AuthorizationException 无授权则抛出例外
     */
    void checkPermission(String permission) throws AuthorizationException;

    /**
     * 检查持有{@code permissions}授权
     *
     * @param permissions 权限集
     * @throws AuthorizationException 无全部授权则抛出例外
     */
    void checkPermissions(String... permissions) throws AuthorizationException;

    /**
     * 判断是否持有{@code roleIdentifier}角色
     *
     * @param roleIdentifier 角色标识符
     * @return {@link boolean},返回{@code true}表示持有,否则返回{@code false}
     */
    boolean hasRole(String roleIdentifier);

    /**
     * 判断是否持有{@code roleIdentifiers}角色
     *
     * @param roleIdentifiers 角色标识符集合
     * @return {@link boolean[]},每一个角色标识符返回一个对应的boolean
     */
    boolean[] hasRoles(List<String> roleIdentifiers);

    /**
     * 是否持有{@code roleIdentifiers}角色
     *
     * @param roleIdentifiers 角色标识符集合
     * @return {@link boolean},全部持有返回{@code true},否则返回{@code false}
     */
    boolean hasAllRoles(Collection<String> roleIdentifiers);

    /**
     * 检查是否持有{@code roleIdentifier}角色
     *
     * @param roleIdentifier 角色标识符
     * @throws AuthorizationException 未持有则抛出例外
     */
    void checkRole(String roleIdentifier) throws AuthorizationException;

    /**
     * 检查是否持有{@code roleIdentifiers}角色
     *
     * @param roleIdentifiers 角色标识符集合
     * @throws AuthorizationException 未全部持有则抛出例外
     */
    void checkRoles(Collection<String> roleIdentifiers) throws AuthorizationException;

    /**
     * 检查是否持有{@code roleIdentifiers}角色
     *
     * @param roleIdentifiers 角色标识符集合
     * @throws AuthorizationException 未全部持有则抛出例外
     */
    void checkRoles(String... roleIdentifiers) throws AuthorizationException;

    /**
     * 是否已通过身份认证
     *
     * @return {@link boolean},返回{@code true}表示通过
     */
    boolean isAuthenticated();

    /**
     * 是否使用记住我功能
     *
     * @return {@link boolean}, 返回{@code true}表示已使用
     */
    boolean isRemembered();

    /**
     * 如果运行在J2EE下，则执行{@code action}
     *
     * @param action {@link Consumer}
     */
    boolean runAtJ2EE(BiConsumer<HttpServletRequest, HttpServletResponse> action);
}
